//*********************************************************************
// Copyright (C) 2014 Hell Prototypes / www.hellprototypes.com
// 
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
//********************************************************************
#include <avr/io.h>
#include <string.h>
#include <avr/interrupt.h>
#include "common.h"

const uint8_t key_value_map[] = {
	250, 231, 210, 186, 158, 126, 86, 0,
};

#define START_ADC()		setbit(ADCA.CH1.CTRL, 7)
#define WAIT_CONVERT()		do{ while(!testbit(ADCA.CH1.INTFLAGS,0)); ADCA.CH1.INTFLAGS = 1;}while(0)

void key_init(void)
{
	// ADC
	ADCA.CALL = SP_ReadCalibrationByte(0x20);
	ADCA.CALH = SP_ReadCalibrationByte(0x21);

	ADCA.CTRLB = 0x64;			// High current limit, signed mode, no free run, 8 bit
	ADCA.PRESCALER = 0x07;		// Prescaler 512 (62.5kHZ ADC clock)
	ADCA.CTRLA		  = 0x01;	// Enable ADC

	ADCA.REFCTRL	  = 0x12;	// REF= VCC/1.6 (3.3V/1.6 = 2.0625V)
	ADCA.CH1.MUXCTRL  = 0x08;	// Channel 1 input: ADC1 pin
	ADCA.CH1.CTRL	  = 0x01;	// Single-ended positive input signal
}

//blocking function
uint8_t get_key_value(uint16_t timeout)
{
	uint8_t  adc0, adc1, key, pressed = KEY_NONE;
	uint16_t time = 0;

	do{
		do{
	        key = KEY_NONE;
			if(testbit(PORT_CTRL_IN,PIN_KEY_MAIN)) {
				key = KEY_MAIN;
			} else	{
				START_ADC();
				WAIT_CONVERT();
				adc0 = ADCA.CH1.RESL;
				if(adc0 <= 250) {
					short_delay();
					START_ADC();
					WAIT_CONVERT();
					adc1 = ADCA.CH1.RESL;
	                if(adc0 - adc1 < 2) {
	    				for(key = 0; key < 8; key++) {
	    					if(adc0 >= key_value_map[key]) {
	    						break;
	    					}
	    				}
	                }
				}
			}
			if(key != KEY_NONE) {
				pressed = key;
			} else {
				if(timeout > 0) {
					time += 10;
					if(time > timeout) {
						return pressed;
					}
				}
			}
			short_delay();
		}while(key != KEY_NONE);
	}while(pressed == KEY_NONE);

	return pressed;
}
